<?
    final class Principio_Model_TypeMapper extends Principio_Mapper
    {
        protected static $db_table = null;
        protected static function getDbTableName() { return "Type"; }


        public static function delete(Principio_Model_Type $model_type)
        {
            try
            {
                self::getDBTable()->getAdapter()->beginTransaction();

                foreach (Principio_Model_TypeInCompanyMapper::fetchByModelType($model_type) as $model_type_in_company)
                    $model_type_in_company->delete();

                $model_type->deleteTemplates();

                self::getDBTable()->delete(['id=?' => $model_type->getID()]);

                $tftp_filename = Principio_Model_SettingMapper::fetch(Principio_Model_SettingMapper::SETTING_TFTP_PATH_TO_INITIAL_CONFIGS)->getValue()."/".$model_type->getTFTPFilename();

                if (!Principio_Common::checkValidity(unlink($tftp_filename), "Can't delete TFTP config file [".$tftp_filename."]."))
                {
                    self::getDBTable()->getAdapter()->rollback();
                    return false;
                };

                self::getDBTable()->getAdapter()->commit();

                return true;
            }
            catch (Exception $ex)
            {
                self::reportException($ex);
                self::getDBTable()->getAdapter()->rollback();

                return false;
            };
        }


        public static function save(Principio_Model_Type $model_type)
        {
            try
            {
                self::getDBTable()->getAdapter()->beginTransaction();

                $data = [
                    'vendor_id' => "-1",
                    'firmware_id' => $model_type->getModelFirmware()->getID(),
                    'tftp_filename' => $model_type->getTFTPFilename(),
                    'caption' => $model_type->getCaption(),
                    'exts' => $model_type->getExts(),
                    'use_default_tftp_config' => new Zend_Db_Expr($model_type->getUseDefaultTFTPConfig()),
                    'tftp_config' => ($model_type->getUseDefaultTFTPConfig() == 0 ? $model_type->getTFTPConfig() : ""),
                    'add_extra_tftp_config' => new Zend_Db_Expr($model_type->getAddExtraTFTPConfig()),
                    'extra_tftp_config' => $model_type->getExtraTFTPConfig(),
                    'use_common_template' => ($model_type->getUseCommonTemplate() ? 1 : 0)
                ];


                if ($model_type->getID() == -1)
                {
                    $model_type->setID(self::getDBTable()->insert($data));
                    $model_type->addTemplates();
                }
                else
                    self::getDBTable()->update($data, ['id=?' => $model_type->getID()]);


                $tftp_filename = Principio_Model_SettingMapper::fetch(Principio_Model_SettingMapper::SETTING_TFTP_PATH_TO_INITIAL_CONFIGS)->getValue()."/".$model_type->getTFTPFilename();

                if (($model_type->getID() != -1) && (!@file_exists($tftp_filename)))
                    Principio_Common::reportWarning("TFTP config [".$tftp_filename."] didn't exist before.");

                if (!Principio_Common::checkValidity(@file_put_contents($tftp_filename, $model_type->getFullTFTPConfig(), LOCK_EX),
                                                            "Can't save ".($model_type->getUseDefaultTFTPConfig() ? "default" : "custom")." TFTP config to a file [".$tftp_filename."].") === true)
                {
                    self::getDBTable()->getAdapter()->rollback();
                    return false;
                }

                self::getDBTable()->getAdapter()->commit();

                return true;
            }
            catch (Exception $ex)
            {
                self::reportException($ex);
                self::getDBTable()->getAdapter()->rollBack();

                return false;
            };
        }


        // TODO - Move to Model
        private static function make($values)
        {
            $model_type = new Principio_Model_Type($values);
            $tftp_filename = Principio_Model_SettingMapper::fetch(
                Principio_Model_SettingMapper::SETTING_TFTP_PATH_TO_INITIAL_CONFIGS)->getValue().
                "/".$model_type->getTFTPFilename();

            if (!@file_exists($tftp_filename))
                Principio_Common::reportError("File [".$tftp_filename."] with TFTP ".($model_type->getUseDefaultTFTPConfig() == 1 ? "default" : "custom")." config doesn't exist.", false);

            return $model_type;
        }


        public static function fetch($id)
        {
            try
            {
                $result = self::getDBTable()->find(intval($id));

                if ($result->count() != 1)
                    throw new Zend_Db_Exception("SPA Type with given ID doesn't exist.");

                return self::make($result[0]->toArray());
            }
            catch (Exception $ex)
            {
                return self::reportException($ex);
            };
        }


        public static function fetchAll()
        {
            try
            {
                $values = self::getDBTable()->fetchAll();
                return Principio_Model_Type::makeCollection($values->toArray());
            }
            catch (Exception $ex)
            {
                return self::reportException($ex);
            };
        }


        public static function checkUniqueTFTPFilename(Principio_Model_Type $model_type)
        {
            try
            {
                $select = self::getDBTable()->select(Zend_Db_Table_Abstract::SELECT_WITH_FROM_PART)->where("tftp_filename=?", $model_type->getTFTPFilename())->where("id<>?", $model_type->getID())->columns("id");
                return (is_null(self::getDBTable()->fetchRow($select)));
            }
            catch (Exception $ex)
            {
                return self::reportException($ex);
            };
        }


        public static function checkUniqueCaption(Principio_Model_Type $model_type)
        {
            try
            {
                $select = self::getDBTable()->select(Zend_Db_Table_Abstract::SELECT_WITH_FROM_PART)->where("caption=?", $model_type->getCaption())->where("id<>?", $model_type->getID())->columns("id");
                return (is_null(self::getDBTable()->fetchRow($select)));
            }
            catch (Exception $ex)
            {
                return self::reportException($ex);
            };
        }


        public static function search($string)
        {
            $search_fields = array(
                "tftp_filename" => "TFTP filename",
                "caption" => "Caption"
            );

            $result = parent::searchInDB(self::getDBTable(), $search_fields, $string);

            foreach ($result as $res)
            {
                $model_search = new Principio_Model_Search($string, "Spa types");
                $menu_data = array("menu_name" => "types", "level" => EXPAND_TYPES, "open_level" => 1);
                $model_search->setId($res["id"])->setResultName($res["caption"])->setOpenItemFunctionName("Types")->setParentID(false)->setMenuData($menu_data);
                foreach ($res as $col_name => $value)
                {
                    if (strstr($value, $string) && in_array($col_name, array_keys($search_fields)))
                        $searchable_text[$search_fields[$col_name]] = $value;
                }
                $model_search->setResult($searchable_text);
                $search[$res["id"]] = $model_search;
            }
            return $search;
        }


        /*
         * set firmware_id = -1
         */
        public static function resetFirmware(Principio_Model_Firmware $model_firmware)
        {
            self::getDBTable()->update(['firmware_id' => "-1"], ['firmware_id=?' => $model_firmware->getID()]);
        }


        public static function usedFirmware(Principio_Model_Firmware $model_firmware)
        {
            try
            {
                $select = self::getDBTable()->select()->where("firmware_id=?", $model_firmware->getID());
                $values = self::getDBTable()->fetchAll($select);

                return Principio_Model_Type::makeCollection($values->toArray());
            }
            catch (Exception $ex)
            {
                return self::reportException($ex);
            };
        }
    }
?>